/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package evocarcassonne.core.generator;

import evocarcassonne.core.board.Tile;
import evocarcassonne.core.utils.Card;
import evocarcassonne.core.utils.Rand;
import evocarcassonne.core.utils.Rot;
import evocarcassonne.core.utils.ZoneType;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author nobpn
 */
public class TileGenerator2 {

    static int number = 0;
    private static Tile tile;
    private static List<TilePattern2> patterns;

    public static Tile firstTile() {
        return newTile();
    }

    public static Tile newTile() {

        patterns = new ArrayList();

        int scenario = Rand.getInt(3);

        scenario = 0;

        switch (scenario) {

            case 0:

                // virgin
                wayVirgin();
                break;

            case 1:
                // opposite
//                wayOpposite();
                break;

            case 2:
                //touchRoad
//                wayTouchRoad();
                break;

        }
//        tile = new Tile(nType, eType, sType, wType);

        tile.number = ++number;

        return tile;

    }

    private static void wayVirgin() {

        int angle = randomAngle();
        angle = Rot.x0;


        int scenario = Rand.getInt(5);

        scenario = 1;

        switch (scenario) {

            case 0:
                // Simple Double Simple
                waySDS(angle);
                genTile();
                break;

            case 1:
                // Simple Triple
                wayTriple(angle);
                genTile();
                break;

            case 2:
                //touchRoad
//                wayRoadTouchCity(angle);
                genTile();
                break;

            case 3:
                // Double Double
                wayDD(angle);
                genTile();
                break;

            case 4:
                // Simple Simple Simple Simple
                waySSSS(angle);
                genTile();
                break;

            case 5:
                wayOpposite(angle);
                genTile();
                break;
        }







    }

    private static void wayOpposite(int angle) {

        int angleS1 = angle;
        int angleOpposite = angle;
        int angleS2 = (angle + Rot.x180) % (Rot.x180 * 2);

        patterns.add(TilePattern2.simpleElt(angleS1));

        //        Double = soit TilePattern2.opposite, soit wayRoadTouchCity2

        wayRoadTouchCity(angleOpposite, 2);

        patterns.add(TilePattern2.simpleElt(angleS2));


    }

    private static void wayRoadTouchCity(int angle, int scenario) {


        if (scenario == 1) {
            // E2N
            int angleCity = (angle + Rot.x180) % (Rot.x180 * 2);
            int angleRoad = angle;
            TilePattern2 cityPattern = TilePattern2.simpleCity(angleCity);
            patterns.add(cityPattern);
            TilePattern2 roadPattern = TilePattern2.touchRoadE2S(angleRoad);
            patterns.add(roadPattern);

        } else if (scenario == 2) {
            int angleCity = (angle + Rot.x90) % (Rot.x180 * 2);
            int angleRoad = angle;
            // OPPOSITE
            TilePattern2 cityPattern = TilePattern2.simpleCity(angleCity);
            patterns.add(cityPattern);
            TilePattern2 roadPattern = TilePattern2.touchRoadOpposite(angleRoad);
            patterns.add(roadPattern);
        } else if (scenario == 3) {
            // E2S
            // TODO ANGLES
            int angleCity = (angle + Rot.x180) % (Rot.x180 * 2);
            int angleRoad = angle;
            TilePattern2 cityPattern = TilePattern2.simpleCity(angleCity);
            patterns.add(cityPattern);
            TilePattern2 roadPattern = TilePattern2.touchRoadW2N(angleRoad);
            patterns.add(roadPattern);
        }
    }

    // Simple Double Simple
    private static void waySDS(int angleS1) {

        int angleD = angleS1;
        int angleS2 = (angleS1 + Rot.x90) % (Rot.x180 * 2);

//        if (Rand.visible()) {
        patterns.add(TilePattern2.simpleElt(angleS1));
//        }
//        if (Rand.visible()) {
//        patterns.add(TilePattern2.simpleElt(angleS2));
//        }

//        Double = soit TilePattern2.doubleElt, soit wayRoadTouchCity 1

//        if (Rand.visible()) {
//        patterns.add(TilePattern2.doubleElt(angleD));
//        }
        wayRoadTouchCity(angleD, 1);
    }

    // Simple Double Simple
    private static void wayDD(int angleD) {

        int angleD2 = (angleD + Rot.x180) % (Rot.x180 * 2);

        //        Double = soit TilePattern2.doubleElt, soit wayRoadTouchCity 1


//        if (Rand.visible()) {
//        patterns.add(TilePattern2.doubleElt(angleD));
        wayRoadTouchCity(angleD, 1);

//        }
//        if (Rand.visible()) {
//        patterns.add(TilePattern2.doubleElt(angleD2));
        wayRoadTouchCity(angleD2, 1);

//        }
    }

    private static void waySSSS(int angle) {

        int angleS1 = angle;
        int angleS2 = (angleS1 + Rot.x90) % (Rot.x180 * 2);
        int angleS3 = (angleS2 + Rot.x90) % (Rot.x180 * 2);
        int angleS4 = (angleS3 + Rot.x90) % (Rot.x180 * 2);

        if (Rand.visible()) {
            patterns.add(TilePattern2.simpleElt(angleS1));
        }
        if (Rand.visible()) {
            patterns.add(TilePattern2.simpleElt(angleS2));
        }
        if (Rand.visible()) {
            patterns.add(TilePattern2.simpleElt(angleS3));
        }
        if (Rand.visible()) {
            patterns.add(TilePattern2.simpleElt(angleS4));
        }
    }

    private static void wayTriple(int angleS) {

        int angleT = angleS;

//        if (Rand.visible()) {
        patterns.add(TilePattern2.simpleElt(angleS));
//        }

        //        Tritple = soit TilePattern2.tripleElt, soit wayRoadTouchDoubleCity


        patterns.add(TilePattern2.tripleElt(angleT));

    }

    private static List<Integer> createMainLink() {

        List<Integer> link = new ArrayList();

        link.add(Card.N);
        link.add(Card.E);
        link.add(Card.S);
        link.add(Card.W);

        return link;

    }

    private static int randomAngle() {
        int angle = Rand.getInt(3);

        switch (angle) {
            case 0:
                angle = Rot.x0;
                break;
            case 1:
                angle = Rot.x90;
                break;
            case 2:
                angle = Rot.x180;
                break;
            case 3:
                angle = Rot.x270;
                break;
        }
        return angle;
    }

    private static void genTile() {

        List<Integer> mainLink = createMainLink();

        ZoneType nType = ZoneType.MEADOW;
        ZoneType eType = ZoneType.MEADOW;
        ZoneType sType = ZoneType.MEADOW;
        ZoneType wType = ZoneType.MEADOW;


        for (TilePattern2 pattern : patterns) {

            if (pattern.otherCards.contains(Card.N) || pattern.card == Card.N) {
                nType = pattern.type;
            }

//            if (pattern.card == Card.N) {
//                nType = pattern.type;
//            }
            if (pattern.otherCards.contains(Card.E) || pattern.card == Card.E) {
                eType = pattern.type;
            }
            if (pattern.otherCards.contains(Card.S) || pattern.card == Card.S) {
                sType = pattern.type;
            }
            if (pattern.otherCards.contains(Card.W) || pattern.card == Card.W) {
                wType = pattern.type;
            }
        }

        // new Tile
        tile = new Tile(nType, eType, sType, wType);



        for (TilePattern2 pattern : patterns) {

            // add To Main Link
            for (Integer card : pattern.addToMain) {
                mainLink.add(card);
            }

            // remove from Main and others link
            for (Integer card : pattern.removeFromLinks) {

                mainLink.remove(card);

                for (TilePattern2 pattern2 : patterns) {

                    if (pattern != pattern2) {
                        for (List<Integer> link : pattern2.newLinks2) {
//                            System.out.println("remove la card " + card + " du pattern " + pattern.hashCode() + " du link " + link + " du pattern " + pattern2.hashCode() + " ?");
                            link.remove(card);
                        }
                    } else {
//                        System.out.println("meme pattern");
                    }
                }
            }

            if (pattern.touch != -1) {
                tile.getZone(pattern.card).setTouch(pattern.touch);
            }

            tile.deadEnds(pattern.deadEnds);

            tile.addPawnLocations(pattern.pawns);
        }

        if (!mainLink.isEmpty()) {
            tile.addPawnLocations(mainLink.get(0));
            if (mainLink.size() > 1) {
                tile.addLink(mainLink);
            }
        }

        for (TilePattern2 pattern : patterns) {

            // newLinks
            for (List<Integer> link : pattern.newLinks2) {

                if (link.size() > 1) {
                    tile.addLink(link);
                } else {
//                    System.out.println("remove link " + link);
                }
            }
        }




//        //links
//        for (TilePattern2 pattern : patterns) {
//
//            // add To Main
//            for (Integer card : pattern.addToMain) {
//                mainLink.add(card);
//            }
//
//
//            // remove from Main and others link
//            for (Integer card : pattern.removeFromLinks) {
//
//                mainLink.remove(card);
//
//
//                for (TilePattern2 pattern2 : patterns) {
//
//                    if (pattern != pattern2) {
//                        for (List<Integer> link : pattern2.newLinks2) {
//
//
//                            System.out.println("remove la card " + card + " du pattern " + pattern.hashCode() + " du link " + link + " du pattern " + pattern2.hashCode() + " ?");
//
//                            link.remove(card);
//
//                        }
//                    } else {
//                        System.out.println("meme pattern");
//                    }
//
//                }
//
//
//            }
//
//            // ROADS
//            if (pattern.type == ZoneType.ROAD) {
//
////                if (pattern.deadEnd) {
////                    tile.deadEnds(pattern.deadEnds);
////
////                    mainLink.add(pattern.deadEnds.get(0) - 1);
////                    mainLink.add(pattern.deadEnds.get(0) + 1);
////
////                } else 
//                if (pattern.touch != -1) {
//
//
//                    tile.getZone(pattern.card).touch = pattern.touch;
//
//
//
////                } else {
//////                    //smallfields for tripleroads
////                    for (List<Integer> smallField : pattern.newLinks) {
////                        tile.addLink(smallField);
////                    }
////
////                    mainLink.add(pattern.linkedMainZones.get(0) - 1);
////                    mainLink.add(pattern.linkedMainZones.get(pattern.linkedMainZones.size() - 1) + 1);
////                }
//                }
//
//            }
//            // Lien principal
//            tile.addLink(mainLink);
//        }



    }
}
